/*******************************************************************************
 * Copyright (c) 2012 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *      Oracle - initial impl
 ******************************************************************************/
package model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.*;
import org.eclipse.persistence.nosql.annotations.DataFormatType;
import org.eclipse.persistence.nosql.annotations.Field;
import org.eclipse.persistence.nosql.annotations.NoSql;

/**
 * Order, stored as a root JSON object, nesting its order lines in the sane document.
 * @author James Sutherland
 */
@Entity
@NoSql(dataFormat=DataFormatType.MAPPED)
public class Order implements Serializable {
    /* The id uses the generated OID (UUID) from Mongo. */
    @Id
    @GeneratedValue
    @Field(name="_id")
    private String id;
    /* Optimistic locking is supported. */
    @Version
    private long version;
    @Basic
    private String description;
    @Basic
    private double totalCost = 0;
    /* A nested embeddable value is stored as Embedded. */
    @Embedded
    private Address billingAddress;
    @Embedded
    private Address shippingAddress;
    /* Nested embeddable values are stored as ElementCollection. */
    @ElementCollection
    private List<OrderLine> orderLines = new ArrayList<OrderLine>();
    /* Relationships are supported, the id is stored as a foreign key, for OneToMany a collection of ids would be stored. */
    @ManyToOne(fetch=FetchType.LAZY)
    private Customer customer;

    public Order() {
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
    
    public long getVersion() {
        return version;
    }

    public void setVersion(long version) {
        this.version = version;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public double getTotalCost() {
        return totalCost;
    }

    public void setTotalCost(double totalCost) {
        this.totalCost = totalCost;
    }

    public List<OrderLine> getOrderLines() {
        return orderLines;
    }

    public void setOrderLines(List<OrderLine> orderLines) {
        this.orderLines = orderLines;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
    
    public Address getBillingAddress() {
        return billingAddress;
    }

    public void setBillingAddress(Address billingAddress) {
        this.billingAddress = billingAddress;
    }

    public Address getShippingAddress() {
        return shippingAddress;
    }

    public void setShippingAddress(Address shippingAddress) {
        this.shippingAddress = shippingAddress;
    }

    /**
     * Add the order line to the order, and set the back reference and update the order cost.
     */
    public void addOrderLine(OrderLine orderLine) {
        getOrderLines().add(orderLine);
        orderLine.setLineNumber(getOrderLines().size());
        setTotalCost(getTotalCost() + orderLine.getCost());
    }

    public String toString() {
        return "Order(" + description + ", " + totalCost + ")";
    }
}
